home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
fortran
/
linpklib.zip
/
SSPCO.FOR
< prev
next >
Wrap
Text File
|
1984-01-07
|
9KB
|
286 lines
SUBROUTINE SSPCO(AP,N,KPVT,RCOND,Z)
INTEGER N,KPVT(1)
REAL AP(1),Z(1)
REAL RCOND
C
C SSPCO FACTORS A REAL SYMMETRIC MATRIX STORED IN PACKED
C FORM BY ELIMINATION WITH SYMMETRIC PIVOTING AND ESTIMATES
C THE CONDITION OF THE MATRIX.
C
C IF RCOND IS NOT NEEDED, SSPFA IS SLIGHTLY FASTER.
C TO SOLVE A*X = B , FOLLOW SSPCO BY SSPSL.
C TO COMPUTE INVERSE(A)*C , FOLLOW SSPCO BY SSPSL.
C TO COMPUTE INVERSE(A) , FOLLOW SSPCO BY SSPDI.
C TO COMPUTE DETERMINANT(A) , FOLLOW SSPCO BY SSPDI.
C TO COMPUTE INERTIA(A), FOLLOW SSPCO BY SSPDI.
C
C ON ENTRY
C
C AP REAL (N*(N+1)/2)
C THE PACKED FORM OF A SYMMETRIC MATRIX A . THE
C COLUMNS OF THE UPPER TRIANGLE ARE STORED SEQUENTIALLY
C IN A ONE-DIMENSIONAL ARRAY OF LENGTH N*(N+1)/2 .
C SEE COMMENTS BELOW FOR DETAILS.
C
C N INTEGER
C THE ORDER OF THE MATRIX A .
C
C OUTPUT
C
C AP A BLOCK DIAGONAL MATRIX AND THE MULTIPLIERS WHICH
C WERE USED TO OBTAIN IT STORED IN PACKED FORM.
C THE FACTORIZATION CAN BE WRITTEN A = U*D*TRANS(U)
C WHERE U IS A PRODUCT OF PERMUTATION AND UNIT
C UPPER TRIANGULAR MATRICES , TRANS(U) IS THE
C TRANSPOSE OF U , AND D IS BLOCK DIAGONAL
C WITH 1 BY 1 AND 2 BY 2 BLOCKS.
C
C KPVT INTEGER(N)
C AN INTEGER VECTOR OF PIVOT INDICES.
C
C RCOND REAL
C AN ESTIMATE OF THE RECIPROCAL CONDITION OF A .
C FOR THE SYSTEM A*X = B , RELATIVE PERTURBATIONS
C IN A AND B OF SIZE EPSILON MAY CAUSE
C RELATIVE PERTURBATIONS IN X OF SIZE EPSILON/RCOND .
C IF RCOND IS SO SMALL THAT THE LOGICAL EXPRESSION
C 1.0 + RCOND .EQ. 1.0
C IS TRUE, THEN A MAY BE SINGULAR TO WORKING
C PRECISION. IN PARTICULAR, RCOND IS ZERO IF
C EXACT SINGULARITY IS DETECTED OR THE ESTIMATE
C UNDERFLOWS.
C
C Z REAL(N)
C A WORK VECTOR WHOSE CONTENTS ARE USUALLY UNIMPORTANT.
C IF A IS CLOSE TO A SINGULAR MATRIX, THEN Z IS
C AN APPROXIMATE NULL VECTOR IN THE SENSE THAT
C NORM(A*Z) = RCOND*NORM(A)*NORM(Z) .
C
C PACKED STORAGE
C
C THE FOLLOWING PROGRAM SEGMENT WILL PACK THE UPPER
C TRIANGLE OF A SYMMETRIC MATRIX.
C
C K = 0
C DO 20 J = 1, N
C DO 10 I = 1, J
C K = K + 1
C AP(K) = A(I,J)
C 10 CONTINUE
C 20 CONTINUE
C
C LINPACK. THIS VERSION DATED 08/14/78 .
C CLEVE MOLER, UNIVERSITY OF NEW MEXICO, ARGONNE NATIONAL LAB.
C
C SUBROUTINES AND FUNCTIONS
C
C LINPACK SSPFA
C BLAS SAXPY,SDOT,SSCAL,SASUM
C FORTRAN ABS,AMAX1,IABS,SIGN
C
C INTERNAL VARIABLES
C
REAL AK,AKM1,BK,BKM1,SDOT,DENOM,EK,T
REAL ANORM,S,SASUM,YNORM
INTEGER I,IJ,IK,IKM1,IKP1,INFO,J,JM1,J1
INTEGER K,KK,KM1K,KM1KM1,KP,KPS,KS
C
C
C FIND NORM OF A USING ONLY UPPER HALF
C
J1 = 1
DO 30 J = 1, N
Z(J) = SASUM(J,AP(J1),1)
IJ = J1
J1 = J1 + J
JM1 = J - 1
IF (JM1 .LT. 1) GO TO 20
DO 10 I = 1, JM1
Z(I) = Z(I) + ABS(AP(IJ))
IJ = IJ + 1
10 CONTINUE
20 CONTINUE
30 CONTINUE
ANORM = 0.0E0
DO 40 J = 1, N
ANORM = AMAX1(ANORM,Z(J))
40 CONTINUE
C
C FACTOR
C
CALL SSPFA(AP,N,KPVT,INFO)
C
C RCOND = 1/(NORM(A)*(ESTIMATE OF NORM(INVERSE(A)))) .
C ESTIMATE = NORM(Z)/NORM(Y) WHERE A*Z = Y AND A*Y = E .
C THE COMPONENTS OF E ARE CHOSEN TO CAUSE MAXIMUM LOCAL
C GROWTH IN THE ELEMENTS OF W WHERE U*D*W = E .
C THE VECTORS ARE FREQUENTLY RESCALED TO AVOID OVERFLOW.
C
C SOLVE U*D*W = E
C
EK = 1.0E0
DO 50 J = 1, N
Z(J) = 0.0E0
50 CONTINUE
K = N
IK = (N*(N - 1))/2
60 IF (K .EQ. 0) GO TO 120
KK = IK + K
IKM1 = IK - (K - 1)
KS = 1
IF (KPVT(K) .LT. 0) KS = 2
KP = IABS(KPVT(K))
KPS = K + 1 - KS
IF (KP .EQ. KPS) GO TO 70
T = Z(KPS)
Z(KPS) = Z(KP)
Z(KP) = T
70 CONTINUE
IF (Z(K) .NE. 0.0E0) EK = SIGN(EK,Z(K))
Z(K) = Z(K) + EK
CALL SAXPY(K-KS,Z(K),AP(IK+1),1,Z(1),1)
IF (KS .EQ. 1) GO TO 80
IF (Z(K-1) .NE. 0.0E0) EK = SIGN(EK,Z(K-1))
Z(K-1) = Z(K-1) + EK
CALL SAXPY(K-KS,Z(K-1),AP(IKM1+1),1,Z(1),1)
80 CONTINUE
IF (KS .EQ. 2) GO TO 100
IF (ABS(Z(K)) .LE. ABS(AP(KK))) GO TO 90
S = ABS(AP(KK))/ABS(Z(K))
CALL SSCAL(N,S,Z,1)
EK = S*EK
90 CONTINUE
IF (AP(KK) .NE. 0.0E0) Z(K) = Z(K)/AP(KK)
IF (AP(KK) .EQ. 0.0E0) Z(K) = 1.0E0
GO TO 110
100 CONTINUE
KM1K = IK + K - 1
KM1KM1 = IKM1 + K - 1
AK = AP(KK)/AP(KM1K)
AKM1 = AP(KM1KM1)/AP(KM1K)
BK = Z(K)/AP(KM1K)
BKM1 = Z(K-1)/AP(KM1K)
DENOM = AK*AKM1 - 1.0E0
Z(K) = (AKM1*BK - BKM1)/DENOM
Z(K-1) = (AK*BKM1 - BK)/DENOM
110 CONTINUE
K = K - KS
IK = IK - K
IF (KS .EQ. 2) IK = IK - (K + 1)
GO TO 60
120 CONTINUE
S = 1.0E0/SASUM(N,Z,1)
CALL SSCAL(N,S,Z,1)
C
C SOLVE TRANS(U)*Y = W
C
K = 1
IK = 0
130 IF (K .GT. N) GO TO 160
KS = 1
IF (KPVT(K) .LT. 0) KS = 2
IF (K .EQ. 1) GO TO 150
Z(K) = Z(K) + SDOT(K-1,AP(IK+1),1,Z(1),1)
IKP1 = IK + K
IF (KS .EQ. 2)
* Z(K+1) = Z(K+1) + SDOT(K-1,AP(IKP1+1),1,Z(1),1)
KP = IABS(KPVT(K))
IF (KP .EQ. K) GO TO 140
T = Z(K)
Z(K) = Z(KP)
Z(KP) = T
140 CONTINUE
150 CONTINUE
IK = IK + K
IF (KS .EQ. 2) IK = IK + (K + 1)
K = K + KS
GO TO 130
160 CONTINUE
S = 1.0E0/SASUM(N,Z,1)
CALL SSCAL(N,S,Z,1)
C
YNORM = 1.0E0
C
C SOLVE U*D*V = Y
C
K = N
IK = N*(N - 1)/2
170 IF (K .EQ. 0) GO TO 230
KK = IK + K
IKM1 = IK - (K - 1)
KS = 1
IF (KPVT(K) .LT. 0) KS = 2
IF (K .EQ. KS) GO TO 190
KP = IABS(KPVT(K))
KPS = K + 1 - KS
IF (KP .EQ. KPS) GO TO 180
T = Z(KPS)
Z(KPS) = Z(KP)
Z(KP) = T
180 CONTINUE
CALL SAXPY(K-KS,Z(K),AP(IK+1),1,Z(1),1)
IF (KS .EQ. 2) CALL SAXPY(K-KS,Z(K-1),AP(IKM1+1),1,Z(1),1)
190 CONTINUE
IF (KS .EQ. 2) GO TO 210
IF (ABS(Z(K)) .LE. ABS(AP(KK))) GO TO 200
S = ABS(AP(KK))/ABS(Z(K))
CALL SSCAL(N,S,Z,1)
YNORM = S*YNORM
200 CONTINUE
IF (AP(KK) .NE. 0.0E0) Z(K) = Z(K)/AP(KK)
IF (AP(KK) .EQ. 0.0E0) Z(K) = 1.0E0
GO TO 220
210 CONTINUE
KM1K = IK + K - 1
KM1KM1 = IKM1 + K - 1
AK = AP(KK)/AP(KM1K)
AKM1 = AP(KM1KM1)/AP(KM1K)
BK = Z(K)/AP(KM1K)
BKM1 = Z(K-1)/AP(KM1K)
DENOM = AK*AKM1 - 1.0E0
Z(K) = (AKM1*BK - BKM1)/DENOM
Z(K-1) = (AK*BKM1 - BK)/DENOM
220 CONTINUE
K = K - KS
IK = IK - K
IF (KS .EQ. 2) IK = IK - (K + 1)
GO TO 170
230 CONTINUE
S = 1.0E0/SASUM(N,Z,1)
CALL SSCAL(N,S,Z,1)
YNORM = S*YNORM
C
C SOLVE TRANS(U)*Z = V
C
K = 1
IK = 0
240 IF (K .GT. N) GO TO 270
KS = 1
IF (KPVT(K) .LT. 0) KS = 2
IF (K .EQ. 1)